package com.nulldev.util.data;

import java.util.concurrent.atomic.AtomicReference;

import com.nulldev.util.io.FastIO.FastIO;

/**
 * variable, a tiny container for variables. Was previously var until JRE 10.
 * 
 * @author null
 * @since 2.6, renamed in 3.0.0.
 * @param <T>
 */
public class variable<T> {
	private final AtomicReference<T> obj = new AtomicReference<T>();

	public variable() {
		this(null);
	}

	public variable(final T obj) {
		this.obj.lazySet(obj);
	}

	public T object() {
		return this.obj.get();
	}

	public T get() {
		return this.obj.get();
	}

	public T value() {
		return this.obj.get();
	}

	public void update(final T obj) {
		this.obj.set(obj);
	}

	public void set(final T obj) {
		this.obj.set(obj);
	}

	public variable<T> setAndReturnSelf(final T obj) {
		this.obj.set(obj);
		return this;
	}

	public void setObject(final T obj) {
		this.obj.set(obj);
	}

	public void lazySet(final T value) {
		this.obj.lazySet(value);
	}

	@Deprecated
	public FinalBypass<T> toBypass() {
		return new FinalBypass<T>(this.obj.get());
	}

	@Override
	public String toString() {
		if (this.obj.get().getClass().isAssignableFrom(String.class)) {
			return (String) this.obj.get();
		} else {
			return String.valueOf(this.obj.get());
		}
	}

	public void println() {
		FastIO.get().println(this.obj.get());
	}

	public boolean notNull() {
		return this.obj.get() != null;
	}

	public boolean isNull() {
		return this.obj.get() == null;
	}

	/* NCOMPAT: finalize() was removed as JRE 18 removes finalization. */

	public T getObject() {
		return this.obj.get();
	}

	public static <T> variable<T> makeLocked(final T value) {
		return new variable<T>(value) {
			@Override
			public void set(final T obj) {
			};

			@Override
			public void setObject(final T obj) {
			};

			@Override
			public void update(final T obj) {
			};

			@Override
			public void lazySet(final T value) {
			}

			@Override
			public variable<T> setAndReturnSelf(final T obj) {
				return this;
			}
		};
	}
}
